package com.songlanyun.modules.coupon.model.vo;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.annotation.TableField;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.songlanyun.common.drive.ValueObject;
import com.songlanyun.common.enums.CouponConstant;
import com.songlanyun.common.enums.MarketingConstant;
import com.songlanyun.common.utils.custom.MathUtils;
import com.songlanyun.modules.coupon.service.CouponGoodsService;
import com.songlanyun.modules.coupon.service.CouponShopService;
import com.songlanyun.modules.goods.model.vo.GoodsSuperSlimVo;
import com.songlanyun.modules.rabbitmq.util.SpringContextUtil;
import com.songlanyun.modules.shop.model.vo.ShopSlimVO;
import lombok.Data;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.Range;

import javax.validation.constraints.DecimalMax;
import javax.validation.constraints.DecimalMin;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.util.*;

@Data
public class CouponEntityVo implements ValueObject {
    {
        threshold = BigDecimal.ZERO;
        issueNumber = -1;
        expiredDay = 7;
        adaptOrNo = true;
    }
    /**
     *
     */
    private Long id;
    /**
     * 优惠券名称
     */
    private String name;

    /**
     * 编号
     */
    private String code;

    /**
     * 描述
     */
    private String content;

    /**
     * 优惠券范围 0:平台券，1:店铺券
     */
    private CouponConstant.CouponMode mode;

    /**
     * 优惠券特征 0:普通券，1:新人券
     */
    private CouponConstant.CouponTrait trait;

    /**
     * 是否是通用券
     */
    private Boolean universal;
    /**
     * 0:满减券
     */
    private CouponConstant.CouponType type;
    /**
     * 优惠券优惠额度
     */
    private BigDecimal faceValue;
    /**
     * 是否存在门槛
     */
    private Boolean hasThreshold;
    /**
     * 门槛值
     */
    private BigDecimal threshold;
    /**
     * 发行数量(-1代表不限量)
     */
    private Integer issueNumber;

    /**
     * 领取后过期天数
     */
    private Integer expiredDay;
    /**
     * 0000001，适应首单优惠1，00000010适应秒杀2，00000100适应拼团4
     */
    private Integer adaptActivity;

    private List<AdaptActivityVo> adaptActivityData;

    public List<AdaptActivityVo> getAdaptActivityData()
    {
        if(CollectionUtil.isEmpty(adaptActivityData)) {
            adaptActivityData = new ArrayList<>();
            Set<Map.Entry<CouponConstant.ActivityCouponType, Integer>> entries = CouponConstant.ADAPT_ACTIVITY.entrySet();
            for (Map.Entry<CouponConstant.ActivityCouponType, Integer> entry : entries) {
                CouponConstant.ActivityCouponType key = entry.getKey();
                Integer value = entry.getValue();
                AdaptActivityVo adaptActivityVo = new AdaptActivityVo();
                adaptActivityVo.setCode(key.getCode());
                adaptActivityVo.setOn(MathUtils.andOperation(value, this.adaptActivity));
                adaptActivityData.add(adaptActivityVo);
            }
        }
        return adaptActivityData;
    }
    /**
     * 是否适配首单优惠
     * @return
     */
    public Boolean isAdaptFirstOrder()
    {
        return MathUtils.andOperation(CouponConstant.ADAPT_ACTIVITY.get(CouponConstant.ActivityCouponType.FIRST_ORDER), this.adaptActivity);
    }

    /**
     * 是否适配秒杀
     * @return
     */
    public Boolean isAdaptSecKill()
    {
        return MathUtils.andOperation(CouponConstant.ADAPT_ACTIVITY.get(CouponConstant.ActivityCouponType.SECKILL), this.adaptActivity);
    }

    /**
     * 是否适配拼团
     * @return
     */
    public Boolean isAdaptGroupBuy()
    {
        return MathUtils.andOperation(CouponConstant.ADAPT_ACTIVITY.get(CouponConstant.ActivityCouponType.GROUP_BUY), this.adaptActivity);
    }

    /**
     * 领取数量
     */
    private Integer receiveNum;

    /**
     * 每人限领多少张（用了之后给再领取）
     */
    private Integer receiveLimit;
    /**
     * 开始时间
     */
    private Date startTime;

    /**
     * 活动状态
     * @return
     */
    /**
     * 活动状态
     * @return
     */
    public CouponConstant.UseStatus getActiveState()
    {
        Date now = new Date();
        if(CouponConstant.CouponStatus.STOP.equals(this.getStatus()))
        {
            return CouponConstant.UseStatus.STOP;
        }

        if(DateUtil.compare(now,this.getEndTime())>=0)
        {
            return CouponConstant.UseStatus.COMPLETE;
        }

        if(CouponConstant.CouponStatus.WAIT_RELEASE.equals(this.getStatus()))
        {
            return CouponConstant.UseStatus.WAIT_RELEASE;
        }

        if(CouponConstant.CouponStatus.RELEASED.equals(this.getStatus()) &&  DateUtil.compare(now,this.getStartTime()) >= 0 && DateUtil.compare(now,this.getEndTime()) < 0)
        {
            return CouponConstant.UseStatus.NORMAL;
        }

        if(CouponConstant.CouponStatus.RELEASED.equals(this.getStatus()) &&  DateUtil.compare(now,this.getStartTime()) < 0 )
        {
            return CouponConstant.UseStatus.RELEASED;
        }


        return CouponConstant.UseStatus.COMPLETE;
    }

    /**
     * 是否可以领取
     * @param num
     * @return
     */
    public Integer canReceive(Integer num)
    {
        if(CouponConstant.UseStatus.COMPLETE.equals(this.getActiveState()))
        {
            return -1;
        }

        if(CouponConstant.UseStatus.STOP.equals(this.getActiveState()))
        {
            return -2;
        }

        if(CouponConstant.UseStatus.WAIT_RELEASE.equals(this.getActiveState()))
        {
            return -3;
        }

        if(CouponConstant.UseStatus.RELEASED.equals(this.getActiveState()))
        {
            return -4;
        }

        if(this.getIssueNumber()!=-1 && (this.getIssueNumber()-this.getReceiveNum())<num)
        {
            return -5;
        }
        return 1;

    }

    /**
     * 优惠券状态 0已终止，1待发布，2已发布
     */
    private  CouponConstant.CouponStatus status;


    /**
     * 结束时间
     */
    private Date endTime;
    /**
     * 发行的店铺
     */
    private Long shopId;

    /**
     * 适合或不适合（如果是平台券非通用券，指的是指定的店铺是适合或不适合，
     * 如果是店铺券非通用券，指的是指定的商品是适合或不适合）
     */
    private Boolean adaptOrNo;


    /**
     * 如果是平台券，那些店铺适合或不适合
     */
    @TableField(exist = false)
    private List<Long> adaptShops;
    public List<Long> loadAdaptShopIds()
    {
        if(CouponConstant.CouponMode.PLATFORM.equals(this.mode) && adaptShops == null)
        {
            CouponShopService couponShopService = (CouponShopService) SpringContextUtil.getBean("couponShopService");
            adaptShops = couponShopService.loadAdaptShopIds(this.getId());
        }
        return adaptShops;
    }


    /**
     * 如果是店铺券，那些商品适合或不适合
     */
    @TableField(exist = false)
    private List<Long> adaptGoods;
    public List<Long> loadAdaptGoodsIds()
    {
        if(CouponConstant.CouponMode.SHOP.equals(this.mode) &&adaptGoods == null)
        {
            CouponGoodsService couponGoodsService = (CouponGoodsService) SpringContextUtil.getBean("couponGoodsService");
            adaptGoods = couponGoodsService.loadAdaptGoodIds(this.getShopId(),this.getId());
        }
        return adaptGoods;
    }
}
